<template>
  <div class="game-room">
    <div class="left">
      <GameScoreBoard :myScore="myScore" :allScores="allScores" />
    </div>
    <div class="center-content">
      <GameBoard
        :puzzle="puzzle.content"
        :puzzleID="puzzle.id"
        :conflict="conflictStr"
        @answerSubmited="handleSubmitAnswer"
      />
    </div>
    <div class="right">
      <div class="puzzle-info">
        <Alert :show-icon="showPuzzleInfoIcon" class="hidden-less-xsm">
          题目: {{ puzzle.id }}
          <Icon type="ios-game-controller-b-outline" slot="icon"></Icon>
          <template slot="desc">
            难度: {{ room.setting.difficulty | difficultyToStr }}<br />
            共玩: {{ puzzle.playerPlayed }} 次 <br />
            最高分: {{ puzzle.highestScore }} 分
          </template>
        </Alert>
      </div>
      <GameProgress
        class="room-game-progress"
        :myProgress="myProgress"
        :otherProgresses="otherProgresses"
      />

      <div class="room-control">
        <Card :style="{ width: '100%', height: '100%' }">
          <div class="btn-control">
            <Button
              icon="ios-arrow-dropleft"
              type="primary"
              @click="handleLeaveRoom"
              >离开房间</Button
            >
          </div>
        </Card>
      </div>
    </div>
    <GameEndDialog
      v-model="endDialog"
      :gameInfo="gameEndInfo"
      @roomExitClicked="roomExitClicked"
    ></GameEndDialog>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from '@/plugins/class-component-hooks'
import { Emit } from 'vue-property-decorator'
import GameBoard from '@/components/GameBoard.vue'
import GameScoreBoard, { UserScoreInfo } from '@/components/GameScoreBoard.vue'
import GameProgress, { UserProgressInfo } from '@/components/GameProgress.vue'
import GameEndDialog, { GameEndInfo } from '@/components/GameEndDialog.vue'
import { RoomData, PushAnswerMutation } from '../types'
import { windowModule } from '../store'
import { gqlErrorHandler } from '../util/errorHandler'

interface WindowSize {
  innerWidth: number
  innerHeight: number
}

@Component({
  components: {
    GameBoard,
    GameScoreBoard,
    GameProgress,
    GameEndDialog
  }
})
export default class RoomGame extends Vue {
  @Prop() readonly room!: RoomData

  private endDialog: boolean = false

  private conflictStr: string = ''

  get noMePlayers() {
    let meId = this.room.me.id
    return this.room.players.filter(player => player.id !== meId)
  }

  get myProgress(): UserProgressInfo {
    return {
      name: this.room.me.name,
      progress: this.room.me.state.progress
    }
  }

  get otherProgresses(): UserProgressInfo[] {
    return this.noMePlayers.map(player => ({
      name: player.name,
      progress: player.state.progress
    }))
  }

  get myScore(): number {
    return this.room.me.state.gamingScore
  }

  get allScores(): UserScoreInfo[] {
    return this.room.players.map(player => ({
      name: player.name,
      avatarSrc: player.character.imgUrl,
      score: player.state.gamingScore
    }))
  }

  get puzzle() {
    return this.room.puzzle
  }

  get gameEndInfo(): GameEndInfo {
    return {
      gameMode: this.room.setting.mode,
      difficulty: this.room.setting.difficulty,
      score: this.myScore
    }
  }

  get showPuzzleInfoIcon() {
    return windowModule.innerWidth > 768
  }

  @Emit('roomExitClicked')
  roomExitClicked() {}

  handleLeaveRoom() {
    this.endDialog = true
  }

  async submitAnswer(answer: string) {
    let res = await this.$apollo.mutate({
      mutation: require('@/graphql/pushAnswer.gql'),
      variables: {
        answer: answer
      }
    })

    let data: PushAnswerMutation['pushAnswer'] = res.data.pushAnswer
    this.conflictStr = data.conflictElem
  }

  handleSubmitAnswer(answer: string) {
    this.submitAnswer(answer)
      .then(() => {
        this.$Message.success('提交成功!')
      })
      .catch((err: any) => {
        gqlErrorHandler(this, err)
      })
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
@import '@/styles/general.scss';
.game-room {
  display: flex;
  justify-content: space-around;
  margin: 0 auto;

  @media screen and (max-width: $size-xsm) {
    flex-direction: column;

    > :nth-child(n) {
      margin-bottom: 2rem;
    }
  }

  .left {
    flex-basis: 25%;
  }

  .right {
    flex-basis: 25%;
    height: 100%;

    display: flex;
    flex-direction: column;

    & :nth-child(2) {
      flex-grow: 1;
    }
  }

  .puzzle-info {
    width: 100%;
  }

  .room-control {
    margin-top: 1rem;
    min-height: 5rem;
    .btn-control {
      padding-top: 3rem;
      display: flex;
      justify-content: flex-end;
    }
  }
}
</style>
